package com.example.batteryhelper;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Observer;

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;

import com.Ohuang.ilivedata.MyLiveData;
import com.example.batteryhelper.databinding.ActivityMainBinding;

import com.example.batteryhelper.databinding.WindowPowerBinding;
import com.example.batteryhelper.onePx.OnePixelManager;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding activityMainBinding;
    public static final String TAG = "MainActivity";

    private BatteryManager batteryManager;
    private boolean isStart = false;
    private boolean activityFinish = false;
    private double power;//平均功耗计算值
    private int count;//计数
    private ExecutorService executorService;
    private double sumPower = 0;//记录功耗和
    private float sumPowerForOneMin = 0;//记录一分钟内的功耗和
    private static final int OVERLAY_PERMISSION_REQ_CODE = 2;
    private float maxPower = -100000;
    private float minPower = 100000;
    private double sumCurrent = 0;//记录电流和
    private int currentNow = 0;
    private int currentCoefficient = 1;//电流系数

    private SmallWindowView windowView;
    private WindowManager wm;
    private WindowManager.LayoutParams mLayoutParams;
    private boolean isShow = false;
    private WindowPowerBinding windowViewPower;
    private PowerManager.WakeLock mWakeLock = null;

    private long lastTime = 0;
    private long lastGetTime;
    SimpleDateFormat simpleDateFormat;
    private Dialog dialog;
    private Dialog dialog_clear;
    private int percentageStart;
    private int percentageNow;
    private OnePixelManager manager;

    @SuppressLint("WrongConstant")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SpUtil.init(this);
        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
        initSmallViewLayout();
        simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
        MyLiveData.getInstance().with("1", Integer.class).observeForever(observer);
        Intent intent2 = new Intent(this, MyService.class);
        bindService(intent2, connection, BIND_AUTO_CREATE);
        manager = OnePixelManager.get();
        manager.registerOnePixelReceiver(this);//注册广播接收者
        currentCoefficient= SpUtil.get("main").readInt("currentCoefficient",1);
    }

    MyService.MyBinder myBinder;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myBinder = (MyService.MyBinder) service;
            if (myBinder != null) {
                myBinder.getPower();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    Observer<Integer> observer = new Observer<Integer>() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onChanged(Integer integer) {
            int v = getVolt();
            currentNow = integer;
            int a = integer / currentCoefficient;

            float p = (v * a) / 1000.0f;
            float current = a;
            if (lastTime != 0) {
                current = current * ((System.currentTimeMillis() - lastTime) / 1000.0f);
            }
            lastTime = System.currentTimeMillis();
            activityMainBinding.tvPowerNow.setText("电压:" + v + "mV  电流：" + a + "mA 功耗：" + (int) p + "mW");

            if (isShow) {
                windowViewPower.tvCurrent.setText(a + "mA");
                windowViewPower.tvPower.setText((int) p + "mW");
            }
            if (isStart) {
                if (lastGetTime != 0) {
                    if (System.currentTimeMillis() > (lastGetTime + 10000)) {
                        showDialog();
                    }
                }
                if (count == 0) {
                    activityMainBinding.tvDataAvg.append("startTime=" + simpleDateFormat.format(new Date(System.currentTimeMillis())) + "\n");
                    percentageStart = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
                }
                percentageNow = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);

                count++;
                sumPower += p;
                sumPowerForOneMin += p;
                sumCurrent += current;
                power = sumPower / count;
                int work = (int) (sumCurrent * 1000 / 3600);
                maxPower = Math.max(maxPower, p);
                minPower = Math.min(minPower, p);
                activityMainBinding.tvPowerMaxAndMin.setText("最大功耗:" + (int) maxPower + "mW     最小功耗:" + (int) minPower + "mW");
                activityMainBinding.tvPowerAvg.setText("平均功耗(mW):" + (int) power + "mW  电量变化:" + (work / 1000.0f) + "mAh");
                if (Math.abs(percentageNow - percentageStart) > 5) {
                    int data = (int) (Math.abs(work / 10.0f) / Math.abs(percentageNow - percentageStart));
                    activityMainBinding.tvPowerAvg.append("\n电池容量估算:" + data + "mAh");
                } else {
                    activityMainBinding.tvPowerAvg.append("\n电池容量估算:暂无数据(电量变化需要大于5%)");
                }
                activityMainBinding.tvData.append("(" + count + ")" + (int) p + "mW time:" + simpleDateFormat.format(new Date(System.currentTimeMillis())) + ",  ");
                if (count % 2 == 0) {
                    activityMainBinding.tvData.append("\n");
                }
                if (count % 5 == 0) {
                    if (myBinder != null) {
                        myBinder.show("当前功耗为" + p + "mW");
                    }
                }

                if (count % 60 == 0) {
                    activityMainBinding.tvDataAvg.append("第" + count / 60 + "阶段平均功耗:" + (int) (sumPowerForOneMin / 60) + "mW,endTime="
                            + simpleDateFormat.format(new Date(System.currentTimeMillis())) + "\n");
                    sumPowerForOneMin = 0;
                    activityMainBinding.tvData.setText("");
                }
            }
            lastGetTime = System.currentTimeMillis();

        }
    };


    private void showDialog() {
        if (dialog == null) {
            dialog = DialogHelper.DeleteDialogShow(this, "数据获取异常", "由于系统限制,导致无法在后台正常运行,是否现在去进行应用设置?", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    MobileInfoUtils.jumpStartInterface(MainActivity.this);
                }
            });
        }

        dialog.show();
    }


    //获取手机电池电压
    private int getVolt() {
        return registerReceiver((BroadcastReceiver) null, new IntentFilter("android.intent.action.BATTERY_CHANGED")).getIntExtra("voltage", -1);
    }

    public void startLoadData(View view) {
        if (!isStart) {
            isStart = true;
            activityMainBinding.btnStart.setText("停止记录");
            Toast.makeText(this, "后台获取需要设置系统白名单", Toast.LENGTH_LONG).show();
        } else {
            isStart = false;
            activityMainBinding.btnStart.setText("开始记录");
        }
    }

    public void ClearData(View view) {
        dialog_clear = DialogHelper.DeleteDialogShow(this, "清除数据", "你确定要清除记录的数据吗?", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                power = 0;
                sumPower = 0;
                sumPowerForOneMin = 0;
                sumCurrent = 0;
                count = 0;
                maxPower = -100000;
                minPower = 100000;
                activityMainBinding.tvData.setText("");
                activityMainBinding.tvDataAvg.setText("");
                dialog_clear.dismiss();
            }
        });
        dialog_clear.show();

    }


    public int coefficientToSelected(int coefficient) {
        int s = -1;
        while (coefficient > 0) {
            s++;
            coefficient /= 10;
        }
        return s;
    }

    public int selectedToCoefficient(int selected) {
        int c = 1;
        for (int i = 0; i < selected; i++) {
            c *= 10;
        }
        return c;
    }

    public void SettingCurrent(View view) {
        String[] strings = new String[8];
        for (int i = 0; i < strings.length; i++) {
            strings[i] = (currentNow / selectedToCoefficient(i)) + "mA";
        }
        DialogHelper.ChooseDialogShow(this, coefficientToSelected(currentCoefficient), strings, new DialogHelper.ChooseDialogListener() {
            @Override
            public void onClick(int selected) {

                currentCoefficient = selectedToCoefficient(selected);
                SpUtil.get("main").saveData("currentCoefficient", currentCoefficient);
            }
        });
    }


    public void showSmallWindows(View view) {
        if (!isShow) {
            alertWindow();
            isShow = true;
            activityMainBinding.btnSmallWindows.setText("小窗隐藏");
        } else {
            dismissWindow();
            isShow = false;
            activityMainBinding.btnSmallWindows.setText("小窗显示");
        }
    }


    public void initSmallViewLayout() {
        windowView = (SmallWindowView) LayoutInflater.from(this).inflate(R.layout.window_power, null);
        wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        windowViewPower = WindowPowerBinding.bind(windowView);

        mLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
        mLayoutParams.gravity = Gravity.NO_GRAVITY;
        windowView.setWm(wm);
        windowView.setWmParams(mLayoutParams);

    }

    public void alertWindow() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 7.0 以上需要引导用去设置开启窗口浮动权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 8.0 以上type需要设置成这个
                mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            }
            requestDrawOverLays();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 6.0 动态申请
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW}, 1);
        }
    }

    // android 23 以上先引导用户开启这个权限 该权限动态申请不了
    @TargetApi(Build.VERSION_CODES.M)
    public void requestDrawOverLays() {
        if (!Settings.canDrawOverlays(MainActivity.this)) {
            Toast.makeText(this, "can not DrawOverlays", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + MainActivity.this.getPackageName()));
            startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
        } else {
            if (wm != null && windowView.getWindowId() == null) {
                wm.addView(windowView, mLayoutParams);
            }
            Toast.makeText(this, "权限已经授予", Toast.LENGTH_SHORT).show();
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "设置权限拒绝", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "设置权限成功", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 移除window
    public void dismissWindow() {
        if (wm != null && windowView != null && windowView.getWindowId() != null) {
            wm.removeView(windowView);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        dismissWindow();
        activityFinish = true;
        myBinder.stop();
        unbindService(connection);
        MyLiveData.getInstance().with("1", Integer.class).removeObserver(observer);
        manager.unregisterOnePixelReceiver(this);
    }
}